/**
 * 
 */
package br.com.framework.apresentacao.filter;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.transaction.Status;
import javax.transaction.UserTransaction;

import org.apache.log4j.Logger;

/**
 * Classe de filtro responsável por implementar o padrão Open Session In View.
 * Evitando os ocorram os erros de Lazy Loading Initialization.
 * 
 * @author Cleber
 * 
 */
public class TransactionFilter implements Filter {

	private static final Logger LOGGER = Logger
			.getLogger(TransactionFilter.class);

	@Resource
	private UserTransaction userTransaction;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		try {
			userTransaction.begin();
			LOGGER.debug("Transação iniciada no filtro.");
			chain.doFilter(req, res);
			userTransaction.commit();
		} catch (Exception e) {
			LOGGER.error("Houve uma falha no processamento do filtro.", e);
			try {
				LOGGER.debug("Efetuando rollback na transação...");
				userTransaction.rollback();
				LOGGER.debug("Rollback efetuado com sucesso.");
			} catch (Exception e1) {
				LOGGER.error(
						"Falha ao efetuar rollback na transação.", e1);
			}
		} finally {
			try {
				if (userTransaction.getStatus() == Status.STATUS_MARKED_ROLLBACK
						|| userTransaction.getStatus() == Status.STATUS_ROLLING_BACK
						|| userTransaction.getStatus() == Status.STATUS_ROLLEDBACK) {
					LOGGER.debug("Transação foi marcada para rollback!");
					try {
						LOGGER.debug("Efetuando rollback na transação...");
						userTransaction.rollback();
						LOGGER.debug("Rollback efetuado com sucesso.");
					} catch (Exception e1) {
						LOGGER.error(
								"Falha ao efetuar rollback na transação.", e1);
					}
				}
			} catch (Exception e) {
				LOGGER.error("Falha ao commitar transação.", e);
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}

}
